/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.logiclander.ricemine.services.identity;

import com.logiclander.ricemine.utils.LdapUtilities;
import java.text.SimpleDateFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kuali.rice.kim.bo.entity.dto.KimEntityCitizenshipInfo;
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;

/**
 *
 * @author tcarroll
 */
public class LdapKimEntityCitizenshipInfoMapper implements ContextMapper {

  private final Log log = LogFactory.getLog(getClass());
  private String countryCodeAttributeName = null;
  private String citizenshipStatusCodeAttributeName = null;
  private String startDateAttributeName = null;
  private String endDateAttributeName = null;
  private String startDateLdapDateFormat = null;
  private String endDateLdapDateFormat = null;

  //beg: methods required by ContextMapper interface
  public Object mapFromContext(Object ctx) {
    validateConfiguration();
    KimEntityCitizenshipInfo keci = new KimEntityCitizenshipInfo();
    try {
      DirContextAdapter context = (DirContextAdapter) ctx;
      // currently, this assumes that an entity only has one citizenship (the one aligned
      // with this ldap record.  this is a decent assumption for now, but a configurable
      // option for either doing it this way or mapping multiple emails would be better
      // perhaps some organizations have multi-valued attributes that list citizenships

      // the entityCitizenshipId is a synthetic identifier for the instance of an entity citizenship.
      // this should be unique in the system, but there is no graceful way to do this
      // from an ldap mapping
      keci.setEntityCitizenshipId("1");//is there an ldap attribute for this?
      keci.setCountryCode(LdapUtilities.materialize(context.getStringAttribute(countryCodeAttributeName)));
      keci.setCitizenshipStatusCode(LdapUtilities.materialize(context.getStringAttribute(citizenshipStatusCodeAttributeName)));
      keci.setStartDate(new SimpleDateFormat(startDateLdapDateFormat).parse(LdapUtilities.materialize(context.getStringAttribute(startDateAttributeName),"01/01/1900")));
      keci.setEndDate(new SimpleDateFormat(endDateLdapDateFormat).parse(LdapUtilities.materialize(context.getStringAttribute(endDateAttributeName),"01/01/1900")));
      keci.setActive(true);//is there an ldap attribute for this?
    } catch (Throwable t) {
      log.error("Error in ContextMapper", t);
      String msg = "ContextMapper failed to create a LdapRecord from the specified Context: " + ctx;
      throw new RuntimeException(msg, t);
    }
    if (log.isDebugEnabled()) {
      log.debug("mapped LdapKimEntityCitizenship:"
              + "(entityCitizenshipId=" + keci.getEntityCitizenshipId() + ")"
              + "(coutryCode=" + keci.getCountryCode() + ")"
              + "(isActive=" + keci.isActive() + ")");
    }
    return keci;
  }

//end: methods required by ContextMapper interface
//beg: helper methods
  public String getCountryCodeAttributeName() {
    return this.countryCodeAttributeName;
  }

  public void setCountryCodeAttributeName(String attrName) {
    this.countryCodeAttributeName = attrName;
  }

  public String getCitizenshipStatusCodeAttributeName() {
    return this.citizenshipStatusCodeAttributeName;
  }

  public void setCitizenshipStatusCodeAttributeName(String attrName) {
    this.citizenshipStatusCodeAttributeName = attrName;
  }

  public String getStartDateAttributeName() {
    return this.startDateAttributeName;
  }

  public void setStartDateAttributeName(String attrName) {
    this.startDateAttributeName = attrName;
  }

  public String getEndDateAttributeName() {
    return this.endDateAttributeName;
  }

  public void setEndDateAttributeName(String attrName) {
    this.endDateAttributeName = attrName;
  }

  public String getStartDateLdapDateFormat() {
    return this.startDateLdapDateFormat;
  }

  public void setStartDateLdapDateFormat(String attrName) {
    this.startDateLdapDateFormat = attrName;
  }

  public String getEndDateLdapDateFormat() {
    return this.endDateLdapDateFormat;
  }

  public void setEndDateLdapDateFormat(String attrName) {
    this.endDateLdapDateFormat = attrName;
  }

  private void validateConfiguration() {
    if (countryCodeAttributeName == null) {
      String msg = "The property 'countryCodeAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (citizenshipStatusCodeAttributeName == null) {
      String msg = "The property 'citizenshipStatusCodeAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (startDateAttributeName == null) {
      String msg = "The property 'startDateAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (startDateAttributeName == null) {
      String msg = "The property 'startDateAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (startDateLdapDateFormat == null) {
      String msg = "The property 'startDateLdapDateFormat' must be set.";
      throw new IllegalStateException(msg);
    }
    if (endDateLdapDateFormat == null) {
      String msg = "The property 'endDateLdapDateFormat' must be set.";
      throw new IllegalStateException(msg);
    }
  }
//end: helper methods
}
